home *** CD-ROM | disk | FTP | other *** search
/ Windows Expert / Windows Expert.iso / windownt / lpr10.zip / LP.C next >
C/C++ Source or Header  |  1992-11-02  |  3KB  |  139 lines

  1. /*
  2.  * tcp_util.c
  3.  *
  4.  *
  5.  * by Eric Brown
  6.  *    27 October '92
  7.  */
  8. #include <windows.h>
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <stdlib.h>
  12. #include <winsock.h>
  13. #include <time.h>
  14.  
  15. #include "lp.h"
  16.  
  17. char *lp_printcap_server_lookup(char *printer)
  18. {
  19.     return NULL;
  20. } /* lp_printcap_server_lookup() */
  21.  
  22. int lp_tcp_startup()
  23. {
  24.     WSADATA    WSAData;
  25.     return WSAStartup(0x0001, &WSAData);
  26. } /* lp_tcp_startup() */
  27.  
  28. void lp_tcp_shutdown()
  29. {
  30. } /* lp_tcp_shutdown() */
  31.  
  32.  
  33. /*
  34.  * NOTES:
  35.  *  This code is modified from _UNIX_NETWORK_PROGRAMMING_ by W. Richard Stevens,
  36.  *  pp. 398-399.
  37.  */
  38. int lp_tcp_open(char *host)
  39. {
  40.     struct sockaddr_in    tcp_srv_addr;
  41.     struct sockaddr_in    tcp_my_addr;
  42.     struct hostent        tcp_host_info, *hp;
  43.     unsigned long        inaddr;
  44.     int                    fd;
  45.     int                    retries;
  46.     int                    b_nolinger;
  47.     struct linger        linger;
  48.     
  49.     memset((void *)&tcp_srv_addr, 0, sizeof(tcp_srv_addr));
  50.     tcp_srv_addr.sin_family =AF_INET;
  51.     tcp_srv_addr.sin_port = htons((short)PRINTER_PORT);
  52.     
  53.     /*
  54.      * First try to convert the host name as a dotted-decimal number.
  55.      * Only if that fails do we call gethostbyname()
  56.      */
  57.     if ((inaddr = inet_addr(host)) != INADDR_NONE) {
  58.         memcpy((void *)&tcp_srv_addr.sin_addr, (const void *)&inaddr,
  59.                sizeof(inaddr));
  60.         tcp_host_info.h_name = NULL;
  61.     }
  62.     else
  63.     {
  64.         if ((hp = gethostbyname(host)) == NULL) {
  65.             fprintf(stderr, "tcp_open: hst name error: %s\n", host);
  66.             return -1;
  67.         } /* if */
  68.         tcp_host_info = *hp;
  69.         memcpy((void *)&tcp_srv_addr.sin_addr, (const void *)hp->h_addr,
  70.                hp->h_length);
  71.     } /* else */
  72.     
  73.     
  74.     /*
  75.      * Create an internet domain socket
  76.      */
  77.     if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
  78.         fprintf(stderr, "tcp_open: can't get a reserved TCP port\n");
  79.         return -1;
  80.     } /* if */
  81.     
  82.     
  83.     /*
  84.      * Bind to a privledged port
  85.      */
  86.     memset((void *)&tcp_my_addr, 0, sizeof(tcp_my_addr));
  87.     tcp_my_addr.sin_family = AF_INET;
  88.     lp_randomize();
  89.     retries = BIND_RETRIES;
  90.     while((tcp_my_addr.sin_port = htons((short)(rand() % MAX_PRIV_PORT)),
  91.            bind(fd, (struct sockaddr *)&tcp_my_addr, sizeof(struct sockaddr)))) {
  92.             if (WSAGetLastError() == WSAEADDRINUSE && retries-- > 0)
  93.                 continue; /* Try again */
  94.             else {
  95.                 fprintf(stderr, "tcp_open: Couldn't bind.\n");
  96.                 closesocket(fd);
  97.                 return -1;
  98.             } /* else */
  99.     } /* while */
  100.     if (retries == 0) {
  101.         fprintf(stderr, "tcp_open: Tried %d ports, couldn't bind to any.\n",
  102.                 BIND_RETRIES);
  103.         closesocket(fd);
  104.         return -1;
  105.     } /* if */
  106.     
  107.  
  108.     /*
  109.      * Connect to the server
  110.      */
  111.     if (connect(fd, (struct sockaddr *)&tcp_srv_addr, sizeof(struct sockaddr)) < 0) {
  112.         fprintf(stderr, "tcp_open: can't connect to server\n");
  113.         closesocket(fd);
  114.         return -1;
  115.     } /* if */
  116.     
  117.     
  118.     /*
  119.      * Let us linger for 1 AND ONLY 1 second!
  120.      *  Without this bit of code, I found that doing an lpq or lprm
  121.      *  immediately after an lpr would frequently fail! -Eric.
  122.      */
  123.     b_nolinger = (int)FALSE; /* turn off DONTLINGER = turn on LINGER */
  124.     linger.l_onoff = 1;
  125.     linger.l_linger = 1; /* 1 second */
  126.     setsockopt(fd, SOL_SOCKET, SO_DONTLINGER, (char *)&b_nolinger, sizeof(b_nolinger));
  127.     setsockopt(fd, SOL_SOCKET, SO_LINGER, (char *)&linger, sizeof(linger));
  128.  
  129.  
  130.     return(fd);
  131. } /* tcp_open() */
  132.  
  133.  
  134. void lp_randomize()
  135. {
  136.     srand((unsigned)time(NULL));
  137. } /* lp_randomize() */
  138.  
  139.